﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using ZedGraph;
using PFI.ADCConv;
using Utils.SignalGenerator;
using Utils.Statistics;

namespace Utils.GlobalGathering
{
    public static class ADCCharacteristicHelper
    {
        public static PointPairList[] GetDiagramOfTransformation(GlobalUnit unit, CharacteristoOfTransformationParametrs param, out Dictionary<int, int[]> regTrack)
        {
            PointPairList[] graphArrays = new PointPairList[3];

            unit.SetAdcNewWeights();

            PointPairList[] res = unit.adcInst.GetDiagramOfTransformation(param, out regTrack);

            graphArrays[0] = res[0].Clone();
            graphArrays[1] = res[1].Clone();

            unit.CalibrationsOfADC();

            res = unit.adcInst.GetDiagramOfTransformation(param, out regTrack);

            graphArrays[2] = res[1].Clone();

            return graphArrays;
        }

        public static Dictionary<UnLinearityType, Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>>> GetStatisticsOfDiagramOfTransformation(GlobalUnit unit, int numbers)
        {
            Dictionary<UnLinearityType, Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>>> result =
                new Dictionary<UnLinearityType, Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>>>(2);
            Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>> dictIntegralUnLinearity =
                new Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>>(2);
            Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>> dictDiferentialUnLinearity =
                new Dictionary<ModellingDataType, Dictionary<StatisticParametrType, double>>(2);

            Dictionary<int, int[]> regTrack;

            double[] simpleIntegral=new double[numbers];
            double[] calibratedIntegral=new double[numbers];

            double[] simpleDifferential=new double[numbers];
            double[] calibratedDifferential=new double[numbers];

            CharacteristoOfTransformationParametrs param =
                new CharacteristoOfTransformationParametrs(int.MaxValue, 1,
                    new AnalogSignal(TypesOfSignalEnum.KxB, new LineParametrs(1.0, 0.0)));

            for (int index = 0; index<numbers; index++)
            {
                PointPairList[] graphArrays = GetDiagramOfTransformation(unit, param, out regTrack);
                PointPairList[] integralUnLinearityCurve=Nonlinearity.CalculateIntegralUnLinearity(graphArrays[1], graphArrays[2]);
                PointPairList[] diferentialUnLinearityCurve = Nonlinearity.CalculateDifferentialUnLinearity(graphArrays[1], graphArrays[2]);

                CalculateStatisticsForOneParametr(integralUnLinearityCurve,ref simpleIntegral[index],ref calibratedIntegral[index]);
                CalculateStatisticsForOneParametr(diferentialUnLinearityCurve, ref simpleDifferential[index], ref calibratedDifferential[index]);
            }

            dictIntegralUnLinearity.Add(ModellingDataType.Simple,MakeLowestDictionary(simpleIntegral));
            dictIntegralUnLinearity.Add(ModellingDataType.Calibrated, MakeLowestDictionary(calibratedIntegral));

            dictDiferentialUnLinearity.Add(ModellingDataType.Simple, MakeLowestDictionary(simpleDifferential));
            dictDiferentialUnLinearity.Add(ModellingDataType.Calibrated, MakeLowestDictionary(calibratedDifferential));

            result.Add(UnLinearityType.Integral, dictIntegralUnLinearity);
            result.Add(UnLinearityType.Differential, dictDiferentialUnLinearity);

            return result;
            
        }
        static void CalculateStatisticsForOneParametr(PointPairList[] unLinearityCurve, ref double simple, ref double calibrated)
        {
            double[] result = new double[2];

            double[] mas = unLinearityCurve[0].PointPairListGetY();
            //для оцінювання береться максимальне значення нелінійності на ХП
            simple = MasFunctions.GetMax(mas);

            mas = unLinearityCurve[1].PointPairListGetY();
            //для оцінювання береться максимальне значення нелінійності на ХП
            calibrated = MasFunctions.GetMax(mas);
        }
        static Dictionary<StatisticParametrType, double> MakeLowestDictionary(double[] mas)
        {
            Dictionary<StatisticParametrType, double> result = new Dictionary<StatisticParametrType, double>(2);
            result.Add(StatisticParametrType.Mean, MasFunctions.CalculateMean(mas));
            result.Add(StatisticParametrType.Variation, MasFunctions.CalculateVariation(mas));

            return result;
        }
    }
}
